Skip to content

refactor(community): give the provider port vendor-neutral types - #68

Merged
yufoxda merged 2 commits into
developfrom
refactor/community-neutral-types
Jul 27, 2026
Merged

refactor(community): give the provider port vendor-neutral types#68
yufoxda merged 2 commits into
developfrom
refactor/community-neutral-types

Conversation

@yufoxda

@yufoxda yufoxda commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

#62 の再作成です。#61 のマージでベースブランチが削除され、GitHub が #62 を自動クローズしたため、内容そのままで develop 向けに出し直しました(#62 はレビュー済み)。

CommunityProvider は名前だけが汎用で、中身は Discord 固有でした。

何が問題だったか

  • ポートのメソッドが DiscordGuildMembership / DiscordMessage / DiscordReactionUser を返していた
  • 全IDが Discord の snowflake 形式(^\d{17,20}$)で検証され、その正規表現がアプリ層まで到達していた
  • Discord の2000文字制限がポートの型に焼き込まれていた

プロバイダを差し替えるには「アダプタを入れ替える」のではなく、インターフェースと api_v0 のサービスを書き換える必要がありました。

変更内容

ポート(中立)CommunityRole / CommunityMembership / CommunityMessage / CommunityReactionUser / CommunityAccountProfile。IDは不透明な文字列として扱い、メッセージ長制限も削除。

アダプタ(Discord固有)lib/community/discord/schema.ts に snowflake 検証・2000文字制限・global_name の写像を集約。中立スキーマを .extend() して精緻化するため検証は緩みません

挙動は不変

snowflake 検証に依存する以下のテストが移動後も通ります。

  • getCurrentDiscordUser rejects malformed provider responses as a bad gateway
  • getGuildMembershipAPI rejects a guild member response for another user

境界の確認

  • interface.ts / type.ts に Discord 語彙なし(コメントを除く)
  • api_v0 に Discord 固有型の参照なし
  • DiscordSnowflakeSchemalib/community/discord/ 配下のみ

🤖 Generated with Claude Code

yufoxda and others added 2 commits July 27, 2026 16:45
The port was generic in name only. Its methods returned DiscordGuildMembership,
DiscordMessage and DiscordReactionUser, and every identifier was validated
against the Discord snowflake format, so the identifier regex reached callers
that have no reason to know what a snowflake is. Replacing the provider would
have meant editing the interface and both api_v0 services rather than swapping
an adapter.

The port now speaks CommunityRole, CommunityMembership, CommunityMessage,
CommunityReactionUser and CommunityAccountProfile, treats identifiers as opaque
strings, and drops the Discord message length limit. Discord's snowflake
format, its 2000-character limit, and the global_name field it returns are
refinements applied in discord/schema.ts, which is the only layer that issues
those values. The provider-specific field name is mapped to displayName at the
adapter boundary, matching the provider_display_name column it is stored in.

Behaviour is unchanged: the adapter still rejects a malformed provider response
and a guild member response for another user, both of which depend on the
snowflake assertion that moved.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yufoxda
yufoxda merged commit e4db694 into develop Jul 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant